package chances.system.log.interceptor;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.fasterxml.jackson.databind.ObjectMapper;

import chances.system.log.entity.ActionLog;
import chances.system.operator.entity.Operator;
import chances.system.operator.entity.Oplog;
import chances.system.operator.service.OperatorService;
import chances.system.operator.web.LogModel;
import chances.system.operator.web.OperatorSession;


public class LogInterceptor extends HandlerInterceptorAdapter {
	
	public static final String LOG_LIST = "log_list";
	
	@Autowired
	private OperatorService operatorService;
	
	ObjectMapper objectMapper = new ObjectMapper();
	
	@SuppressWarnings("unchecked")
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
				
		if ((handler instanceof HandlerMethod)) {
			HandlerMethod handlerMethod = (HandlerMethod) handler;
    		Method method = handlerMethod.getMethod();
			ActionLog log = method.getAnnotation(ActionLog.class);  
			Operator operator = null;
			
	        if (log != null) { 
				if(request.getAttribute(log.operator()) != null){
					operator = (Operator)request.getAttribute(log.operator());
				}else{
					Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
					if(authentication != null){
						operator = ((OperatorSession)authentication.getPrincipal()).getOperator();
					}
				}
				
				//指定了objName但是没有request中找到对象说明正确,否则说明错误
				Integer result = Oplog.OPER_SUCCESS;
				String objName = log.objName();
				Object object= null;
	        	String objType = "";
				if (StringUtils.isNotBlank(objName)) {
					object=  request.getAttribute(log.objName());
		        	if(object != null){
		        		objType = object.getClass().getSimpleName().toLowerCase();
		        		result = Oplog.OPER_SUCCESS;
		        	}else{
		        		result = Oplog.OPER_ERROR;
		        	}
				}	        	

        		String desc = log.desc();
	        	if(StringUtils.isNotBlank(desc)){
	        		if (object != null) {
	        			String json=objectMapper.writeValueAsString(object);
	        			Map<String,Object> map = (Map<String,Object>)objectMapper.readValue(json, Map.class);
			        	for (String key : map.keySet()) {
			        		String value = "";
			        		if(map.get(key) != null){
			        			value = map.get(key).toString();
			        		}
			        		desc = desc.replace("{"+key+"}", value);
						}
					}else{
						desc = "";
					}
	        	}
	        	
				Oplog oplog = new Oplog(operator, log.operateType(),objType , 
						method.getDeclaringClass().getName(), result, desc);
				operatorService.save(oplog);
	        }
		}
		super.postHandle(request, response, handler, modelAndView);
	}
	
	@SuppressWarnings("unchecked")
	public List<LogModel> getLogList(HttpServletRequest request){
		Object object = request.getAttribute(LogInterceptor.LOG_LIST);
		if(object != null){
			return (List<LogModel>)object;
		}
		return null;
	}	
}